package publish

import (
	"crypto/aes"
	"crypto/cipher"
	"crypto/rand"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io"
	"os"
	"path/filepath"
)

// Config 存储用户配置
type TokenConfig struct {
	APIToken string `json:"api_token"`
}

// 加密密钥（实际应用中应更安全地生成和存储）
var encryptionKey = []byte("nest-32-byte-encryption-key-must") // 必须为16、24或32字节

// 配置文件路径
func configPath() (string, error) {
	home, err := os.UserHomeDir()
	if err != nil {
		return "", fmt.Errorf("获取用户主目录失败: %v", err)
	}
	return filepath.Join(home, ".nest", "token.json"), nil
}

// SaveConfig 加密并保存配置
func SaveToken(token string) error {

	var cfg = &TokenConfig{APIToken: token}
	path, err := configPath()
	if err != nil {
		return err
	}

	// 确保目录存在
	dir := filepath.Dir(path)
	if _, err := os.Stat(dir); os.IsNotExist(err) {
		if err := os.MkdirAll(dir, 0700); err != nil {
			return fmt.Errorf("创建配置目录失败: %v", err)
		}
	}

	// 序列化为JSON
	jsonData, err := json.Marshal(cfg)
	if err != nil {
		return fmt.Errorf("序列化配置失败: %v", err)
	}

	// 加密数据
	encryptedData, err := encrypt(jsonData)
	if err != nil {
		fmt.Println("encryptedData:", encryptedData)
		return fmt.Errorf("加密配置失败: %v", err)
	}

	// 写入文件
	return os.WriteFile(path, []byte(base64.StdEncoding.EncodeToString(encryptedData)), 0600)
}

// LoadConfig 解密并加载配置
func GetToken() (TokenConfig, error) {
	var cfg TokenConfig
	path, err := configPath()
	if err != nil {
		return cfg, err
	}

	// 检查文件是否存在
	if _, err := os.Stat(path); os.IsNotExist(err) {
		return cfg, nil // 返回空配置
	}

	// 读取文件
	data, err := os.ReadFile(path)
	if err != nil {
		return cfg, fmt.Errorf("读取配置失败: %v", err)
	}

	// 解码Base64
	encryptedData, err := base64.StdEncoding.DecodeString(string(data))
	if err != nil {
		return cfg, fmt.Errorf("解码配置失败: %v", err)
	}

	// 解密数据
	decryptedData, err := decrypt(encryptedData)
	if err != nil {
		return cfg, fmt.Errorf("解密配置失败: %v", err)
	}

	// 反序列化为结构体
	if err := json.Unmarshal(decryptedData, &cfg); err != nil {
		return cfg, fmt.Errorf("解析配置失败: %v", err)
	}

	return cfg, nil
}

// AES加密函数
func encrypt(data []byte) ([]byte, error) {
	block, err := aes.NewCipher(encryptionKey)
	if err != nil {
		return nil, err
	}

	gcm, err := cipher.NewGCM(block)
	if err != nil {
		return nil, err
	}

	nonce := make([]byte, gcm.NonceSize())
	if _, err = io.ReadFull(rand.Reader, nonce); err != nil {
		return nil, err
	}

	ciphertext := gcm.Seal(nonce, nonce, data, nil)
	return ciphertext, nil
}

// AES解密函数
func decrypt(ciphertext []byte) ([]byte, error) {
	block, err := aes.NewCipher(encryptionKey)
	if err != nil {
		return nil, err
	}

	gcm, err := cipher.NewGCM(block)
	if err != nil {
		return nil, err
	}

	nonceSize := gcm.NonceSize()
	if len(ciphertext) < nonceSize {
		return nil, fmt.Errorf("密文长度不足")
	}

	nonce, ciphertext := ciphertext[:nonceSize], ciphertext[nonceSize:]
	plaintext, err := gcm.Open(nil, nonce, ciphertext, nil)
	if err != nil {
		return nil, err
	}

	return plaintext, nil
}
